<?php

namespace common\observer;

use support\SingletonTrait;
use common\service\EntityService;
use common\service\StatusService;
use common\service\CommonService;
use think\module\Module;
use teamones\dbeventObserver\interfaces\SplSubject;
use teamones\dbeventObserver\interfaces\SplObserver;

/**
 * 概念的剧集和场次 同步到资产/关卡
 */
class DesignChangeSyncToAssetLevel implements SplObserver
{
    use SingletonTrait;

    public $syncFields = [
        'name',
        'description',
        'is_assignee',
        'frame_range',
        'category_id',
        'start_time',
        'end_time',
        'duration',
        'estimate_hours',
        'cost_hours',
        'hour_proportion',
        'is_manual_adjustment',
        'plan_start_time',
        'plan_end_time',
        'character_seal',
        'showings_number',
        'remark',
        'is_confirm',
        'director_star',
        'key_shot',
        'is_append',


        'initial_episode_code',

        'design_skip_remove_rigging_control',


    ];


    protected $timeFields = [
        'plan_start_time',
        'plan_end_time',
        'start_time',
        'end_time',
    ];

    /**
     * @param SplSubject $subject
     * @return void
     */
    function update(SplSubject $subject): void
    {
        $entity = $subject->getSubjectData();
        $updateData = $subject->getSplUpdateData();

        if ($entity['module_id'] != module_by_code('design')['id']) {
            return;
        }

        $publishedStatusList = StatusService::getInstance()->getEntityPublishedStatusList('design');
        $publishedStatusList = array_column($publishedStatusList, 'id');

        $designStatus = json_decode($entity['json'] ?? '{}', true)['design_status'] ?? null;
        // 没有发布过的概念 不需要处理
        if (empty($designStatus) || !in_array($designStatus, $publishedStatusList)) {
            return;
        }

        // 求出变化的字段和要同步的字段的交集
        $changedFieldIntersect = array_intersect($this->syncFields, array_keys($updateData));
        if (empty($changedFieldIntersect)) {
            return;
        }
        // 查询下游实体
        $downEntity = EntityService::getInstance()->getDownstreamEntity($entity);
        if (empty($downEntity)) {
            return;
        }

        $downEntityModuleData = module_by_id($downEntity['module_id']);
        $syncData = [
            'id' => $downEntity['id'],
        ];


        $customFields = Module::$moduleDictData['field_index_by_code']['design']['custom'] ?? [];
        $customFields = array_keys($customFields);
        foreach ($changedFieldIntersect as $updateKey) {
            if ($updateKey === 'name') {
                // 同步名称 需要保证code同时传递 不然code会自动生成
                $syncData['code'] = $entity['code'];
            }
            $v = $updateData[$updateKey];
            if (in_array($updateKey, $this->timeFields)) {
                $v = date("Y-m-d H:i:s", $v);
            }
            if (in_array($updateKey, $customFields)) {
                $newUpdateKey = str_replace_once('design', $downEntityModuleData['code'], $updateKey);
                $syncData[$newUpdateKey] = $v;
            } else {
                $syncData[$updateKey] = $v;
            }
        }

        try {
            request()->getModuleCode($downEntityModuleData['code']);
            CommonService::instance('entity')->update($syncData, $downEntityModuleData['code'], false);
        } catch (\Throwable $e) {
            trace(format_exception_info($e), 'ERR');
        }
    }
}
